package org.e_gold.safe.acc.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.e_gold.dto.Browser;
import org.e_gold.dto.Cookies;
import org.e_gold.model.Cookie;
import org.e_gold.model.UserAccount;
import org.e_gold.service.impl._NavigatorAbstract;
import org.e_gold.util.BrowserTypeENUM;
import org.e_gold.util.Constant;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

abstract class TSAAuthorizeAbstract extends _NavigatorAbstract implements Constant {

    private static final Logger log = Logger.getLogger(TSAAuthorizeAbstract.class);

    protected static Browser ipad;

    private static final String TXT_USER_NAME = "txtUserName";
    private static final String TXT_PASSWORD = "txtPassword";
    private static final String MAIN_TXT_USER_NAME = "ctl00$main$login$UserName";
    private static final String MAIN_TXT_PASSWORD = "ctl00$main$login$Password";

    private Document initLoginPage() {

        Document loginPage = null;
        try {
            if (ipad == null) {
                ipad = new Browser();
                ipad.setBrowserType(BrowserTypeENUM.IPAD_VERSION.toString());
                ipad.setHeaders(prepareBasicHeaders(ipad.getBrowserType()));
            }
            // navigate to bet365.com
            loginPage = redirectNavigator(MEMBER_HOMEPAGE_URL, ipad);
        } catch (Exception e) {
            log.error(ToStringBuilder.reflectionToString(e, ToStringStyle.SHORT_PREFIX_STYLE));
        }
        return loginPage;
    }

    private Map<String, String> prepareFormData(Document loginPage, UserAccount user) {

        if (loginPage != null) {
            Map<String, String> formData = new HashMap<String, String>();
            Elements els = loginPage.select("input");
            if (CollectionUtils.isNotEmpty(els)) {
                for (Element e : els) {
                    if (e != null && StringUtils.isNotEmpty(e.attr("name"))) {
                        String name = e.attr("name");
                        formData.put(name, e.attr("value"));
                        if (TXT_USER_NAME.equalsIgnoreCase(name) || MAIN_TXT_USER_NAME.equalsIgnoreCase(name))
                            formData.put(name, user.getUserName());
                        else if (TXT_PASSWORD.equalsIgnoreCase(name) || MAIN_TXT_PASSWORD.equalsIgnoreCase(name))
                            formData.put(name, user.getPassword());
                    }
                }
                formData.put("__EVENTTARGET", "ctl00$main$login$lkSbmt");
                formData.put("bet365ss", "1920 x 1080");
                return formData;
            }
        }
        return null;
    }

    // ////////////////
    // protected area
    // ////////////////
    /**
     * check logined by database cookies
     * **/
    protected Document authenticatedTransferPage(UserAccount user) {

        Document transferPage = null;
        try {
            log.info(":: check authenticated");
            try {
                // reset browser by init db cookies - mother fucker bitches - deo hieu tai sao no lai check order cookies
                if(ipad == null){
                    ipad = new Browser();
                    ipad.setBrowserType(BrowserTypeENUM.IPAD_VERSION.toString());
                    ipad.setHeaders(prepareBasicHeaders(ipad.getBrowserType()));
                    initDBCookies();
                }
                transferPage = initTransferPage();
            } catch (IllegalArgumentException e) {
                log.error(ToStringBuilder.reflectionToString(e, ToStringStyle.SHORT_PREFIX_STYLE));
            }
        } catch (Exception e) {
            log.error(ToStringBuilder.reflectionToString(e, ToStringStyle.SHORT_PREFIX_STYLE));
        }
        return transferPage;
    }

    protected void login(UserAccount user) throws Exception {

        // do login
        Document loginPage = initLoginPage();
        Map<String, String> formData = prepareFormData(loginPage, user);
        if (MapUtils.isNotEmpty(formData)) {
            // submit login form to authorize and get cookies back
            log.info(":: LOGIN FORM DATA");
            for (Entry<String, String> e : formData.entrySet()) {
                log.info(e.getKey() + ":" + e.getValue());
            }
            postForm(SUBMIT_LOGIN_FORM_URL, formData, ipad);
        }
    }

    // ////////////////
    // private area
    // ////////////////

    private void initDBCookies() {

        // init db cookies
        List<Cookie> cookiesDB = cookieDAO.findAll(ipad.getBrowserType());
        if (CollectionUtils.isNotEmpty(cookiesDB)) {
            // re-store cookie for logined session or basic session for the first time
            Cookies cookies = ipad.getCookies();
            if (cookies == null) {
                cookies = new Cookies();
            }
            cookies.setCookies(cookiesDB);
            ipad.setCookies(cookies);
            // prepare header
            ipad.setHeaders(prepareBasicHeaders(ipad.getBrowserType()));
            ipad.getHeaders().put(COOKIE, ipad.getCookies().getCookie());
        }
    }

    private Document initTransferPage() throws IllegalArgumentException {

        // try to go to account/bank/transfer page:
        // looking for ctl00_main_TransferFunds_txtAmount node
        Document transferPage = null;
        if (ipad == null || ipad.getCookies() == null || ipad.getCookies().getCookieMap() == null)
            return null;
        try {
            transferPage = redirectNavigator(BANK_TRANSFER_URL, ipad);
        } catch (IllegalArgumentException ie) {
            log.error("::::: ERROR IllegalArgumentException : verifyLogin !!!");
            throw ie;
        } catch (Exception e) {
            log.error(ToStringBuilder.reflectionToString(e, ToStringStyle.SHORT_PREFIX_STYLE));
        }
        return transferPage;
    }

}
